
template <class PixelFormatClass, unsigned int FVF>
inline VertexBuffer<PixelFormatClass, FVF>::VertexBuffer(){
	m_uiVbSize=450;
	m_uiFlush=100;
	m_uiBase=1000;
	m_uiVtxToLock=0;
//	m_primitiveType=NULL;
	m_pVertexBuffer=NULL;
	m_pDev=NULL;
}

template <class PixelFormatClass, unsigned int FVF>
inline VertexBuffer<PixelFormatClass, FVF>::~VertexBuffer(){

}

template <class PixelFormatClass, unsigned int FVF>
inline bool VertexBuffer<PixelFormatClass, FVF>::Create(IDirect3DDevice9 * pDev, bool bDynamic){
	m_pDev = pDev;
	HRESULT hr= pDev->CreateVertexBuffer(m_uiVbSize* sizeof(PixelFormatClass),(bDynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : 0),	FVF,D3DPOOL_DEFAULT,&m_pVertexBuffer,NULL);
	m_uiBase=0;
	if(hr==D3D_OK)
		return true;
	else
		return false;
}

template <class PixelFormatClass, unsigned int FVF>
inline void VertexBuffer<PixelFormatClass, FVF>::Flush(void){
	int iPrimitiveCount;
	
	if(m_primitiveType==D3DPT_POINTLIST)
		iPrimitiveCount=m_uiVtxToLock;
	else if(m_primitiveType==D3DPT_LINELIST)
		iPrimitiveCount=m_uiVtxToLock/2;
	else if(m_primitiveType==D3DPT_LINESTRIP)
		iPrimitiveCount=m_uiVtxToLock-1;
	else if(m_primitiveType==D3DPT_TRIANGLELIST)
		iPrimitiveCount=m_uiVtxToLock/3;
	else if(m_primitiveType==D3DPT_TRIANGLESTRIP)
		iPrimitiveCount=m_uiVtxToLock-2;
	else if (m_primitiveType == D3DPT_TRIANGLEFAN)
		iPrimitiveCount=m_uiVtxToLock-2;
	else
		iPrimitiveCount = 0;

	HRESULT hr = m_pDev->DrawPrimitive(m_primitiveType, m_uiBase, iPrimitiveCount);
//	assert(hr == D3D_OK);
}

template <class PixelFormatClass, unsigned int FVF>
inline void VertexBuffer<PixelFormatClass, FVF>::Bind(void){
	m_pDev->SetVertexShader(NULL);
	m_pDev->SetFVF(FVF);
	m_pDev->SetStreamSource(0, m_pVertexBuffer,	NULL,sizeof(PixelFormatClass));
}


template <class PixelFormatClass, unsigned int FVF>
inline void VertexBuffer<PixelFormatClass, FVF>:: Draw(PixelFormatClass * pVtxCollection, D3DPRIMITIVETYPE primitiveType, unsigned int uiVtxCount){
	m_primitiveType=primitiveType;
	if(m_uiFlush<uiVtxCount)
		m_uiVtxToLock=m_uiFlush;
	else
		m_uiVtxToLock=uiVtxCount;

	void* pVertices=NULL;
	if(m_uiBase+m_uiVtxToLock>m_uiVbSize){
		m_uiBase=0;
	}
	HRESULT hr = m_pVertexBuffer->Lock(m_uiBase * sizeof(PixelFormatClass),
								m_uiVtxToLock * sizeof(PixelFormatClass),
								(void **) &pVertices,
								m_uiBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);
	
	m_uiVtxProcNow = 0;

	while(m_uiVtxToLock > 0)
	{
		memcpy(pVertices, &pVtxCollection[m_uiVtxProcNow],sizeof(PixelFormatClass)*m_uiVtxToLock);
		m_uiVtxProcNow += m_uiVtxToLock;
		m_pVertexBuffer->Unlock();
		Flush();
		m_uiBase += m_uiVtxToLock;
		
		if (m_uiBase > m_uiVbSize - 1)
			m_uiBase = 0;

		if (m_uiFlush < (uiVtxCount-m_uiVtxProcNow))
			m_uiVtxToLock = m_uiFlush;
		else
			m_uiVtxToLock = uiVtxCount-m_uiVtxProcNow;

		if (m_uiBase + m_uiVtxToLock > m_uiVbSize)
			m_uiBase = 0;

		m_pVertexBuffer->Lock(m_uiBase * sizeof(PixelFormatClass),
									m_uiVtxToLock * sizeof(PixelFormatClass),
									(void **) &pVertices,
									m_uiBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);
	}
	if(m_pVertexBuffer)
		m_pVertexBuffer->Unlock();
}